/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//    Copyright(c) 2001 Intel Corporation. All Rights Reserved.
//
//  VSS: 
//     $Workfile: $
//     $Revision: $
//     $Date:     $
//     $Archive:  $
//
//  Description:
//
//  History:
//     Date        Author        Changes
//     2001/8/7   Jerry Hu       Created  (Version 0.1)
//
********************************************************************************/

#include <stdio.h>
#include <stdlib.h>

#include <string.h>
#include <memory.h>

#include "ijx.h"

#include "dib.h"
#include "jpgcmd.h"

///////////////////////////////////////////////////////////////////////////////
//  DIBtoJPEG
int BMPtoJPEG ( int      nQuality,
                int      nRestartInterval,
                int      nJPEGMode,
                int      nSubsampling,
                MDIBSPEC *pDIBSpec,
                FILE     *file)
{
    int              nBufLen; 
    Ipp8u            *pBuf;
    int              nImageStep;
    Ipp8u            *pImageBuf; 
    IJBITTREAMSTATE  stream;
    IIPIMAGESPEC     imageSpec;
    IJENCODESTATE    encodeState;
    IJXRESULT        rtCode;

    fseek(file, 0, SEEK_SET);
    memset(&encodeState, 0, sizeof(IJENCODESTATE));
    memset(&stream, 0, sizeof(IJBITTREAMSTATE));

    /* Init imageSpec */
    imageSpec.nWidth               = pDIBSpec->nWidth;
    imageSpec.nHeight              = pDIBSpec->nHeight;
    imageSpec.nPrecision           = pDIBSpec->nPrecision;
    imageSpec.nNumComponent        = pDIBSpec->nNumComponent;
    imageSpec.nDensityUnit         = 0;
    imageSpec.nXDensity            = 72;
    imageSpec.nYDensity            = 72;
    imageSpec.nColorMode           = pDIBSpec->nClrMode;
    imageSpec.nBitsPerpixel        = pDIBSpec->nBitsPerpixel;
    imageSpec.nSamplingMode        = nSubsampling;


    /* Init stream */

    /* Initialize to 0 */
    stream.nUsedBufBitsLen         = 0; 
    stream.nPrefetchedBits         = 0;
    stream.nNumValidPrefetchedBits = 0;
    stream.nMarker                 = 0;

    /* Estimate the compressed file size */
    if (10240>pDIBSpec->nDataSize) {
        stream.nMaxBufLen          = 10240;
    } else {
        stream.nMaxBufLen          = pDIBSpec->nDataSize;
    }
    stream.pBitStream              = (Ipp8u *)malloc(stream.nMaxBufLen);

    if (NULL==stream.pBitStream) {
        return FALSE;
    }

    /* Init JPEG encoder */
    rtCode = ijxCompressInit( nQuality,
                              nRestartInterval,
                              nJPEGMode&IJX_MODE_STILL_MASK,
                              &imageSpec,
                              NULL,
                              NULL,
                              &stream,
                              &encodeState);

    if (!IJX_SUCCEEDED(rtCode)) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }
    
    /* Get buffers' size for the compressing */
    rtCode = ijxGetCompBufLen(&nBufLen, &encodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }

    /* Init buffer for Encoding */
    pBuf=malloc(nBufLen);
    if (NULL==pBuf) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }

    rtCode = ijxCompBufInit(pBuf, nBufLen, &encodeState);
    if (!IJX_SUCCEEDED(rtCode)) {
        free(stream.pBitStream);
        stream.pBitStream=NULL;
        return FALSE;
    }

    /* Init ImageData */
    /* Bitmap in windows is store from bown to top with BGR format */
    nImageStep = -(pDIBSpec->nStep);
    pImageBuf  = &pDIBSpec->pBitmapData[pDIBSpec->nStep*(pDIBSpec->nHeight-1)]; 
                           
	/* Compressing */
    rtCode=ijxCompress((void **)&pImageBuf,
                       &nImageStep,
                       &stream,
                       &encodeState);

    if (!IJX_SUCCEEDED(rtCode)){
        free(stream.pBitStream);
        stream.pBitStream=NULL;

        free(pBuf);
        pBuf=NULL;

        return FALSE;
    }

    /* End of Compression */
    rtCode=ijxCompress(NULL, NULL,
                       &stream,
                       &encodeState);
    if (IJX_SUCCEEDED(rtCode)){
        fwrite(stream.pBitStream, 1, ((stream.nUsedBufBitsLen+7)>>3), file);
    }

    free(stream.pBitStream);
    stream.pBitStream=NULL;

    free(pBuf);
    pBuf=NULL;

    return IJX_SUCCEEDED(rtCode)? TRUE : FALSE;
}


/* EOF */
